﻿#include "clipboardManager.h"
#include "clipboardStorage.h"
#include <QApplication>
#include <QDebug>
#include <QUrl>
#include <QFileInfo>
#include <QDesktopServices>
#include <QStandardPaths>
#include <QUuid>
#include <QDir>
#include <QFileInfo>
#include <QRegExp>
#include "searchManager.h"
#include "QTextEdit"
#include "QLineEdit"
#include "QMessageBox"
#include <QLabel>
#include <QVBoxLayout>
#include <QScrollArea>
#include "ItemEditorWindow.h"
using namespace std;

/**
 * 剪切板的处理
 * @brief ClipboardManager::ClipboardManager
 * @param parent
 */

ClipboardManager::ClipboardManager(QObject* parent)
    : QObject(parent), clipboard(QApplication::clipboard()) {

    connect(clipboard, &QClipboard::changed, this, &ClipboardManager::checkClipboard);

    setClipboardType(ClipboardType::All);
    setClipboardFavorite(false);

    // 获取当前项目文件夹路径
    QString projectFolderPath = QApplication::applicationDirPath();
    qDebug() << "Project folder path:" << projectFolderPath;
    // 设置 tempFileStorage 文件夹路径
    QString tempFolderPath = QDir(projectFolderPath).filePath("tempFileStorage");

    // 检查 tempFileStorage 文件夹是否存在，如果不存在则创建
    if (!QDir(tempFolderPath).exists()) {
        QDir().mkdir(tempFolderPath);
        qDebug() << "Created tempFileStorage folder at" << tempFolderPath;
    }

    // 导入数据
    storage = new ClipboardStorage();
    storage->importData("D:/exportData.txt");
}

// 导出数据
ClipboardManager::~ClipboardManager() {
    qDebug() << "ClipboardManager" ;
    storage->exportData("D:/exportData.txt");
}

// 复制板启动
void ClipboardManager::startMonitoring() {
    qDebug() << "Clipboard monitoring started.";
}


// 辅助函数，检查是否存在重复项
bool ClipboardManager::isDuplicate(const ClipboardItem& newItem) const {
    for (const ClipboardItem& item : storage->getItems()) {
        if (item.getType() == newItem.getType()) {

            if (item.getType() == ClipboardType::Url) {
                // 使用 QUrl 比较两个 URL 是否相同
               QUrl itemUrl(item.getDisplayText());
               QUrl newUrl(newItem.getDisplayText());

                // 规范化 URL
               itemUrl.setScheme(itemUrl.scheme().toLower());  // 转换为小写
               newUrl.setScheme(newUrl.scheme().toLower());  // 转换为小写
               itemUrl.setHost(itemUrl.host().toLower());  // 转换为小写
               newUrl.setHost(newUrl.host().toLower());  // 转换为小写

               // 手动移除末尾斜杠
               QString itemPath = itemUrl.path();
               if (!itemPath.isEmpty() && itemPath[itemPath.length() - 1] == '/') {
                   itemPath.chop(1); // 移除最后一个字符（斜杠）
               }
               QString newPath = newUrl.path();
               if (!newPath.isEmpty() && newPath[newPath.length() - 1] == '/') {
                   newPath.chop(1); // 移除最后一个字符（斜杠）
               }
               //完成规范
               itemUrl.setPath(itemPath);
               newUrl.setPath(newPath);

                if (itemUrl == newUrl) {
                    return true;  // 找到相同内容的 URL 项
                }
            }
            else if (item.getType() == ClipboardType::File){
                //存放路径里有重复就是true
                if (item.getFileInStorage() == newItem.getFileInStorage()){
                    return true;
                }
            }
            else if (item.getContent() == newItem.getContent()) {
                return true;  // 找到相同类型且相同内容的项
            }
        }
    }
    return false;
}

// 辅助函数，比较图片是否有重复项
//bool ClipboardManager::isImageDuplicate(const ClipboardItem& newItem) const{
//    for(const ClipboardItem& item : storage->getItems()){
//        if(item.getType() == ClipboardType::Image){
//            // 对比图片url
//           if(item.getContent() == newItem.getContent()){
//               return true;
//           }else{
//               // 对比图片的Image
//               QImage newImage = newItem.getContent().value<QImage>();
//               const QString imagePath = item.getContent().toString();
//               QImage oldImage(imagePath);
//               if (newImage == oldImage) {
//                  return true;
//               }
//           }
//        }
//    }
//    return false;
//}

// 检查元素是否相同，不同则保存到剪贴板
void ClipboardManager::checkClipboard() {
    const QMimeData* currentData = clipboard->mimeData();
    if (!currentData) { return; }

    // 处理文件路径类型的内容
    if (currentData->hasUrls()) {
        QList<QUrl> urls = currentData->urls();
        if (!urls.isEmpty()) {
            // 文件
            if (urls.first().isLocalFile()) {
                QString filePath = urls.first().toLocalFile();
                if (filePath == lastFilePath) { return; }  // 简单去重
                lastFilePath = filePath;

                ClipboardItem item = ClipboardItem(ClipboardType::File, filePath);
                if (filePath.endsWith(".jpg", Qt::CaseInsensitive) ||
                    filePath.endsWith(".jpeg", Qt::CaseInsensitive) ||
                    filePath.endsWith(".png", Qt::CaseInsensitive)) {
                    QImage image(filePath);
                    item = ClipboardItem(ClipboardType::Image, image);
                }

                if (!isDuplicate(item)) {  // 检查是否重复
                    storage->addFileItem(item);
                    emit updateItem(this->type, this->favorite, true);
                    QCoreApplication::processEvents();
                    qDebug() << "New file added:" << filePath;
                }
            }
        }
    }
    // 处理文本或URL类型
    else if (currentData->hasText()) {
        QString text = currentData->text();
        if (text == lastText) { return; }
        lastText = text;

        ClipboardItem item = ClipboardItem(ClipboardType::Text, text);

        // 复制的文本可能是一个网页
        QRegExp urlPattern("(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]*[-A-Za-z0-9+&@#/%=~_|]");
        QUrl url(text);
        if (url.isValid()&&urlPattern.indexIn(text) != -1) { //&& !url.scheme().isEmpty()&&text.indexOf("://")!=-1
            item = ClipboardItem(ClipboardType::Url, text);
        }

        if (!isDuplicate(item)) {  // 检查是否重复
            storage->addItem(item);
            emit updateItem(this->type, this->favorite, true);
            QCoreApplication::processEvents();

            // 弹出对话框询问用户是否要打开 URL
            if(item.getType()==ClipboardType::Url){
               SearchManager::askToSearch(item);
            }

            qDebug() << "New text or url item added:" << text;
        }
    }
    // 处理图片类型
    else if (currentData->hasImage()) {
        QImage image = qvariant_cast<QImage>(currentData->imageData());
        QString imagePath = currentData->imageData().toString();
        if (image == lastImage) { return; }
        lastImage = image;

        ClipboardItem item(ClipboardType::Image, image);
        if (!isDuplicate(item)) {  // 检查是否重复
            storage->addItem(item);
            emit updateItem(this->type, this->favorite, true);
            QCoreApplication::processEvents();
            qDebug() << "New image item added.";
        }
    } else {
        qDebug() << "Unsupported clipboard content.";
    }
}


// 获取所有元素
vector<ClipboardItem> ClipboardManager::getAllItems(ClipboardType type, bool favorite, const QString& searchQuery) {
    vector<ClipboardItem> items = storage->getItems();
    vector<ClipboardItem> result;

    for (const auto& item : items) {
        bool matchesSearch = false;

        // 如果搜索框不为空，进行匹配
        if (searchQuery.isEmpty()) {
            matchesSearch = true;
        } else {
            // 根据不同类型进行匹配
            if (item.getType() == ClipboardType::Text) {
                matchesSearch = item.getContent().toString().contains(searchQuery, Qt::CaseInsensitive);
            } else if (item.getType() == ClipboardType::File) {
                matchesSearch = item.getDisplayText().contains(searchQuery, Qt::CaseInsensitive);
            } else if (item.getType() == ClipboardType::Image) {
                matchesSearch = item.getDisplayText().contains(searchQuery, Qt::CaseInsensitive);
            } else if (item.getType() == ClipboardType::Url) {
                matchesSearch = item.getDisplayText().contains(searchQuery, Qt::CaseInsensitive);
            }
        }

        // 筛选符合条件的项
        if (matchesSearch) {
            if (favorite && item.isFavorite()) {
                result.push_back(item);  // 如果是收藏项并且符合搜索
            } else if (!favorite && type == ClipboardType::All) {
                result.push_back(item);  // 显示所有项
            } else if (!favorite && type == item.getType()) {
                result.push_back(item);  // 根据类型筛选项
            }
        }
    }
    return result;
}


void ClipboardManager::copyItem(const ClipboardItem& item) {
    QClipboard *clipboard = QApplication::clipboard();

    // 文本类型的复制
    if (item.getType() == ClipboardType::Text) {
        clipboard->setText(item.getContent().toString());
    }
    // 图片类型的复制
    else if(item.getType() == ClipboardType::Image) {
        const QString imagePath = item.getDisplayText();
        QImage image;
        QString tempPath;

        if (imagePath.isEmpty()) {
            image = item.getContent().value<QImage>(); // 从 QVariant 中提取 QImage
            // 创建临时文件路径
            // 使用 UUID 生成临时文件名
           QString uuid = QUuid::createUuid().toString().remove("{").remove("}");
           tempPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + uuid + ".png";
            image.save(tempPath); // 保存图像到临时文件
        } else {
            image.load(imagePath);
            if (image.isNull()) {
                QMessageBox::information(nullptr, "信息", "无法从文件路径加载图片。");
                return;
            }
            tempPath = imagePath; // 如果是路径，直接使用它
        }

        // 将图片路径设置到剪贴板
        QMimeData *mimeData = new QMimeData;
        mimeData->setImageData(image);
        mimeData->setUrls(QList<QUrl>() << QUrl::fromLocalFile(tempPath));
        clipboard->setMimeData(mimeData);
    }// 文件类型的复制
    else if(item.getType() == ClipboardType::File){
        //获取路径
        const QString filePath = item.getFileInStorage();

        // 检查文件路径是否存在
        QFileInfo fileInfo(filePath);
        if (!fileInfo.exists()) {
            // 路径无效，弹出提示窗口，并2秒后自动消失
            QMessageBox *errorBox = new QMessageBox(QMessageBox::Critical, "信息", "无法从文件路径加载文件。");
            QTimer::singleShot(2000, errorBox, &QMessageBox::accept); // 2秒后自动关闭
            errorBox->setAttribute(Qt::WA_DeleteOnClose); // 确保消息框关闭时被删除
            errorBox->exec();
            return;
        }

        //把要复制的文件路径放到列表里
        QList<QUrl> copyfile;
        QUrl url=QUrl::fromLocalFile(filePath);

        if (url.isValid()) {// 路径存在
            // 保存路径
            copyfile.push_back(url);
            // 存储文件数据
            QMimeData *data=new QMimeData;
            data->setUrls(copyfile);
            // 把数据传到系统剪贴板
            QClipboard *clip=QApplication::clipboard();
            clip->setMimeData(data);
        } else {
            QMessageBox::information(nullptr, "信息", "无法从文件路径加载文件");
            return;
        }
    }// 网页地址的复制
    else if(item.getType() == ClipboardType::Url){
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(item.getContent().toString());
    }// 此外
    else{
        QMessageBox::information(nullptr, "信息", "请确保信息正确");
    }
}


// 删除元素
void ClipboardManager::deleteItem(const ClipboardItem &item) {

    if (item.getType()==ClipboardType::File){
        // 创建一个 QFile 对象
        QFile file(item.getFileInStorage());

        // 删除文件
        if (file.exists() && !file.remove()) {
            QDir dir(item.getFileInStorage());
            if (dir.exists()&&!dir.removeRecursively()){
                // 如果文件或文件夹存在但无法删除，输出错误信息
                qDebug() << "Failed to delete file or dir:" << file.fileName();
            }
        }
        else {
            // 文件删除成功或文件原本就不存在
            qDebug() << "File deleted successfully or file did not exist:" << file.fileName();
        }
    }

    size_t itemIndex = storage->getItemIndex(item);
    storage->removeItem(itemIndex);

    // 检查 item 类型并比较内容，清空相应的缓存数据
    switch (item.getType()) {
        case ClipboardType::Text:
            if (item.getContent().toString() == lastText) {
                lastText.clear();  // 清空 lastText
            }
            break;
        case ClipboardType::File:
            if (item.getContent().toString() == lastFilePath) {
                lastFilePath.clear();  // 清空 lastFilePath
            }
            break;
        case ClipboardType::Image:
            if (item.getContent().value<QImage>() == lastImage) {
                lastImage = QImage();  // 清空 lastImage
            }
            break;
        default:
            break;
    }

    emit updateItem(this->type, this->favorite, false);
    QCoreApplication::processEvents();
}

void ClipboardManager::favoriteItem(const ClipboardItem &item) {
    size_t itemIndex = storage->getItemIndex(item);
    storage->favoriteItem(itemIndex);
    qDebug()<<"已收藏";
}

// 查找元素
void ClipboardManager::searchItem(const ClipboardItem &item) {
    SearchManager::searchOnline(item);
}

// 打开元素
void ClipboardManager::openItem(const ClipboardItem &item) {
    // 先判断是否为文件
    QString filePath = item.getFileInStorage();

    if(QFileInfo(filePath).isDir()||item.getType()== ClipboardType::File){
        // 根据URL打开元素
        if (!QDesktopServices::openUrl(QUrl::fromLocalFile(filePath))) {
            QMessageBox *errorBox = new QMessageBox(QMessageBox::Critical, "打开文件失败", "无法打开文件，请检查路径是否正确。");
            QTimer::singleShot(2000, errorBox, &QMessageBox::accept); // 2秒后自动关闭
            errorBox->exec();
            return;
        }
    }
    else{
        SearchManager::searchOnline(item);
    }

}


//void ClipboardManager::openInstanceItem(const ClipboardItem &item){
//    QString sourceFilePath = item.getDisplayText();
//    QFileInfo sourceFile(sourceFilePath);

//    // 获取当前项目文件夹路径
//    QString projectFolderPath = QApplication::applicationDirPath();
//    QString tempFolderPath = QDir(projectFolderPath).filePath("tempFileStorage");
//    QDir tempDir(tempFolderPath);

//    // 如果 tempFileStorage 文件夹不存在，则创建它
//    QString storageFolderPath = tempDir.filePath("tempFileStorage");
//    QString destinationFilePath = QDir(storageFolderPath).filePath(sourceFile.fileName());
//    qDebug()<<destinationFilePath;

//    // 根据URL打开元素
//    if (!QDesktopServices::openUrl(QUrl::fromLocalFile(destinationFilePath))) {
//        QMessageBox *errorBox = new QMessageBox(QMessageBox::Critical, "打开文件失败", "无法打开文件，请检查路径是否正确。");
//        QTimer::singleShot(2000, errorBox, &QMessageBox::accept); // 2秒后自动关闭
//        errorBox->exec();
//        return;
//    }
//}
void ClipboardManager::getItemDetail(const ClipboardItem &item) {
    ClipboardType type = item.getType();
    QVariant content = item.getContent();

    if (type == ClipboardType::Text || type == ClipboardType::Url) { // 如果item类型为text或url
        QString textContent = content.toString();
        // 创建编辑窗口
        auto *window = new ItemEditorWindow(textContent, storage->getItemIndex(item), storage);
        window->show();  // 显示窗口
    }
    else if (type == ClipboardType::Image) {
        // 创建一个窗口，将content展示在窗口里
        QImage image = content.value<QImage>();
        if (!image.isNull()) {
            auto *window = new QWidget();
            window->setWindowTitle("Clipboard Image");
            auto *scrollArea = new QScrollArea(window);
            auto *label = new QLabel();
            label->setPixmap(QPixmap::fromImage(image));
            scrollArea->setWidget(label);
            scrollArea->setWidgetResizable(true); // 允许滚动区域根据内容调整大小
            auto *layout = new QVBoxLayout(window);
            layout->addWidget(scrollArea);
            window->setLayout(layout);
            window->resize(800, 600); // 设置窗口的初始大小
            window->show();
        } else {
            QMessageBox::warning(nullptr, "Error", "Failed to load image from clipboard.");
        }
    }
}

ClipboardStorage* ClipboardManager::getStorage() {
    return storage;
}


//void ClipboardManager::openInstanceItem(const ClipboardItem &item){
//    QString sourceFilePath = item.getDisplayText();
//    QFileInfo sourceFile(sourceFilePath);

//    // 获取当前项目文件夹路径
//    QString projectFolderPath = QApplication::applicationDirPath();
//    QString tempFolderPath = QDir(projectFolderPath).filePath("tempFileStorage");
//    QDir tempDir(tempFolderPath);

//    // 如果 tempFileStorage 文件夹不存在，则创建它
//    QString storageFolderPath = tempDir.filePath("tempFileStorage");
//    QString destinationFilePath = QDir(storageFolderPath).filePath(sourceFile.fileName());
//    qDebug()<<destinationFilePath;

//    // 根据URL打开元素
//    if (!QDesktopServices::openUrl(QUrl::fromLocalFile(destinationFilePath))) {
//        QMessageBox *errorBox = new QMessageBox(QMessageBox::Critical, "打开文件失败", "无法打开文件，请检查路径是否正确。");
//        QTimer::singleShot(2000, errorBox, &QMessageBox::accept); // 2秒后自动关闭
//        errorBox->exec();
//        return;
//    }
//}
void ClipboardManager::setClipboardType(ClipboardType type) {
    this->type = type;
}

void ClipboardManager::setClipboardFavorite(bool f) {
    this->favorite = f;
}

ClipboardType ClipboardManager::getClipboardType() {
    return this->type;
}

bool ClipboardManager::getCLipboardFavorite() {
    return this->favorite;
}
